package village.rainbow.slipin.ui;

import java.io.File;
import java.lang.ref.WeakReference;

import village.rainbow.slipin.BaseActivity;
import village.rainbow.slipin.R;
import village.rainbow.slipin.adapter.ViewPagerAdapter;
import village.rainbow.slipin.datamodel.DataRow;
import village.rainbow.slipin.datamodel.DataRowBean;
import village.rainbow.slipin.datamodel.DataTable;
import village.rainbow.slipin.ui.carousel.PageScrollCompletedListener;
import village.rainbow.slipin.ui.carousel.UiPagingScrollView;
import village.rainbow.slipin.uicontrol.OnSizeChangedCompleteListener;
import village.rainbow.slipin.uicontrol.SceneView;
import village.rainbow.slipin.util.DateUtil;
import village.rainbow.slipin.util.ExifUtil;
import village.rainbow.slipin.util.StringUtil;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ScaleDrawable;
import android.graphics.drawable.StateListDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Vibrator;
import android.provider.MediaStore;
import android.support.v4.view.ViewPager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.DragEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnDragListener;
import android.view.View.OnLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import android.widget.ToggleButton;

/**
 * 사진을 찍고 메모를 남기며 
 * 일정을 정하고 알람을 설정한다.
 * 공유랑 삭제랑 수정도 되야되네 
 * @author K.O.J
 */
@SuppressLint("WorldReadableFiles")
public class MakeSlipActivity extends BaseActivity implements OnLongClickListener, PageScrollCompletedListener{

	private Uri mCapturedImageUri;
	private int CAMERA_REQUEST = 10001;
	private int GALLERY_REQUEST = 10002;

	private final static int SAVE_MODE_SHARE 	= 1;
	private final static int SAVE_MODE_SHORCUT 	= 2;
	private final static int SAVE_MODE_SAVE 	= 3;

	private DataRow mData;

	private Button mButtonSceneDate;
	private Button mButtonAlarmTime;
		
	private ToggleButton mToggleGps;
	private ToggleButton mToggleShortCut;
	
	// Drag & Drop 
	private Button mScrollLeft;
	private Button mScrollRight;
	
	private UiPagingScrollView mSlipContainer;
	
	private HorizontalScrollView mThumbnailHsv;
	private LinearLayout mThumbnailMain;
	
	private View mDrapView;
	// Drag & Drop
	
	private ExifUtil mExifUtil;
	
	private LayoutInflater mLayoutInflater;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.activity_scene);
		
		mExifUtil = new ExifUtil();
		
		mLayoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		
		TextView tvTitle = (TextView)findViewById(R.id.menu_title);
		tvTitle.setText("Make Slip");
		
		mButtonSceneDate = (Button)findViewById(R.id.btn_slip_date);
		mButtonSceneDate.setText(StringUtil.currentDate("yyyy.MM.dd (a)hh:mm"));
		mButtonSceneDate.setTypeface(Typeface.MONOSPACE);
		mButtonSceneDate.setOnClickListener(this);
		mButtonSceneDate.setTag(StringUtil.currentDate("yyyyMMddHHmmss"));
		
		mButtonAlarmTime = (Button)findViewById(R.id.btn_alarm_time);
		mButtonAlarmTime.setText("No alarm");
		mButtonAlarmTime.setOnClickListener(this);
		
		mToggleGps = (ToggleButton)findViewById(R.id.btn_toggle_gps);
		mToggleGps.setText("");
		mToggleGps.setTextOn("");
		mToggleGps.setTextOff("");
		mToggleGps.setChecked(false);
		setStateDrawable(mToggleGps);
		
		mToggleShortCut = (ToggleButton)findViewById(R.id.btn_toggle_shortcut);
		mToggleShortCut.setText("");
		mToggleShortCut.setTextOn("");
		mToggleShortCut.setTextOff("");
		mToggleShortCut.setChecked(false);
		setStateDrawable(mToggleShortCut);
		
		mScrollLeft = (Button)findViewById(R.id.btn_arrow_left);
		mScrollRight = (Button)findViewById(R.id.btn_arrow_right);
		
		mThumbnailHsv = (HorizontalScrollView)findViewById(R.id.thumbnail_hsv);
		mThumbnailMain = (LinearLayout)findViewById(R.id.thumbnail_main);
		
		mScrollLeft.setOnClickListener(this);
		mScrollRight.setOnClickListener(this);

		bindDrapListener(mScrollLeft);
		bindDrapListener(mScrollRight);
		
		Button btnAdd = (Button)findViewById(R.id.btn_add);
		btnAdd.setOnClickListener(this);
		
		Button btnSave = (Button)findViewById(R.id.btn_save);
		btnSave.setOnClickListener(this);
		
		
	}
	
	@Override
	public void OnSizeChangeComplete() {
		initData();
	}
	
	protected void initData() {
		
		DataTable table = new DataTable();
		Bundle b = getIntent().getExtras();
		if(b != null && b.containsKey("DATA")){
			try{
				DataRowBean bean = (DataRowBean) b.getSerializable("DATA");
				mData = bean.getDataRow();

				table = (DataTable) mData.get("SCENE_DETAIL", new DataTable());
				
				String alarmDate = mData.getString("ALARM_DATE", "");
				mButtonSceneDate.setText(alarmDate);
				
				String sceneDate = mData.getString("SCENE_DATE", "");
				if(sceneDate.equals("")){
					mButtonSceneDate.setTag(sceneDate);
					mButtonSceneDate.setText(DateUtil.toPatternedDate("yyyy.MM.dd (a)hh:mm", "yyyyMMddHHmmss", sceneDate));
				}
				
			}catch(Exception e){
				errorHandler(e);
			}
		}
		
		RelativeLayout slipBase = (RelativeLayout)findViewById(R.id.slip_base);
		if(slipBase.getChildCount() == 0){
			
			int width = (int)(720*getParentRatioW());
			int height = (int)(844*getParentRatioH());
			
			mSlipContainer = new UiPagingScrollView(this, width, height);
			slipBase.addView(mSlipContainer);
			mSlipContainer.setPageScrollCompletedListener(this);
			
			if(!table.isEmpty()){
				for(DataRow row : table){
					addSlipView(row);
					addThumnNail(row);
				}
			}
			
		}
	}
	
	@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
	private void setStateDrawable(View buttonView){
		Drawable viewDrawable = buttonView.getBackground();
		if (viewDrawable == null)
			viewDrawable = new ColorDrawable(Color.TRANSPARENT);
		ColorDrawable wrapDrawable = new ColorDrawable(Color.parseColor("#809ec0ff"));
		Drawable[] layers = {viewDrawable, wrapDrawable};
		LayerDrawable layer = new LayerDrawable(layers);
		StateListDrawable stateDarwable = new StateListDrawable();
		stateDarwable.addState(new int[]{-android.R.attr.state_checked}, viewDrawable);
		stateDarwable.addState(new int[]{android.R.attr.state_checked}, layer);
		stateDarwable.addState(new int[]{}, viewDrawable);
		if(Build.VERSION.SDK_INT > 15){
			buttonView.setBackground(stateDarwable);	
		}else{
			buttonView.setBackgroundDrawable(stateDarwable);
		}
	}
	
	@Override
	public void onClick(View v) {
		super.onClick(v);

		int id = v.getId();
		switch(id){
		case R.id.btn_add:
			choosePic();
			break;
			
		case R.id.imv_picture:
			break;
			
		case R.id.btn_save:
			save();
			break;
			
		case R.id.btn_slip_date:
			showDateTimePicker(mButtonSceneDate);
			break;
			
		case R.id.btn_alarm_time:
			showAlarmPicker();
			break;
			
		case R.id.btn_arrow_left:
			mThumbnailHsv.pageScroll(View.FOCUS_LEFT);
			break;
			
		case R.id.btn_arrow_right:
			mThumbnailHsv.pageScroll(View.FOCUS_RIGHT);
			break;
			
		}

	}
	
	private void showAlarmPicker() {
		final String[] items = new String[]{"No alarm", "5min", "10min", "15min", "30min", "1hour", "2hour", "6hour"};
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("Pick Alarm time when it ringing before");
		builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				mButtonAlarmTime.setText(items[which]);
				dialog.dismiss();
			}
		});
		builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
			}
		});
		builder.create().show();
	}

	private boolean mPreventDoubleClick = false;
	private void choosePic() {

		if(mPreventDoubleClick)
			return;

		mPreventDoubleClick = true;

		try{
			String[] items = {"사진 앨범", "카메라", "사진초기화"};
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("사진 선택");
			builder.setItems(items, new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					switch(which){
					case 0:
						takePicFromGallery();
						break;
					case 1:
						takePic();
						break;
					case 2:
						dialog.dismiss();
						break;
					}
				}
			});
			AlertDialog dialog = builder.create();
			dialog.show();	

			mPreventDoubleClick = false;

		}catch(Exception e){
			errorHandler(e);
		}
	}

	protected void takePicFromGallery() {
		Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
		startActivityForResult(i, GALLERY_REQUEST);
	}

	private String mImgLocation = "";

	private void takePic() {
		try {
			File dir = new File(Environment.getExternalStorageDirectory().getPath() + "/slipin");
			if(!dir.exists())
				dir.mkdir();
			String imageFileName = StringUtil.currentDate("yyyyMMddHHmmss");
			File file = new File(dir, imageFileName + ".png");
			if(file.exists())
				file.delete();
			file.createNewFile();

			mImgLocation = Environment.getExternalStorageDirectory().getPath() + "/slipin/" + imageFileName + ".png"; 

			mCapturedImageUri = Uri.fromFile(file);

			Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
			i.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageUri);
			startActivityForResult(i, CAMERA_REQUEST);
		} catch (Exception e) {
			errorHandler(e);
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
			addPicture(mImgLocation);
		}else if (requestCode == GALLERY_REQUEST && resultCode == RESULT_OK) {
			Uri selectedImage = data.getData();
			String[] filePathColumn = { MediaStore.Images.Media.DATA };
			Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
			cursor.moveToFirst();
			int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
			String picturePath = cursor.getString(columnIndex);
			cursor.close();
			addPicture(picturePath);
		}

	}
	
	private void addPicture(String imgLocation){
		try {
			DataRow row = new DataRow();
			row.put("SCENE_PIC_LOCATION", imgLocation);
			
			addSlipView(row);
			addThumnNail(row);
			
		} catch (Exception e) {
			errorHandler(e);
		}
	}
	private void addSlipView(DataRow row){
		this.addSlipView(row, true);
	}

	private void addSlipView(DataRow row, boolean insFirstFg) {
		SceneView slipV = (SceneView) mLayoutInflater.inflate(R.layout.control_scene, null);
		
		int w = (int)(720 * getParentRatioW());
		int h = (int)(844 * getParentRatioH());
		
		RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(w, h);
		slipV.setLayoutParams(params);
		
		slipV.init(this);
		slipV.setTag(row);
		ImageView imv = (ImageView)slipV.findViewById(R.id.imv_picture);
		imv.setBackgroundColor(Color.BLACK);
		EditText et = (EditText)slipV.findViewById(R.id.edt_memo);
		
		RelativeLayout.LayoutParams etParam = new RelativeLayout.LayoutParams(w, (int)(200*getParentRatioH()));
		etParam.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
		et.setLayoutParams(etParam);
		
		String picturePath = row.getString("SCENE_PIC_LOCATION", "");
		String sceneText = row.getString("SCENE_TEXT", "");
		et.setText(sceneText);
		
		Bitmap bitmap = getScaledDrawable(picturePath, w, h); 
		if(bitmap != null){
			imv.setImageBitmap(bitmap);
		}
		
		if(insFirstFg)
			mSlipContainer.addSlipView(slipV, 0);
		else
			mSlipContainer.addSlipView(slipV, -1);
		
		mSlipContainer.onPageScrollCompleted(mSlipContainer.getCurrentIndex(), mSlipContainer.getTotalPageCount());
	}
	
	private void addThumnNail(DataRow row){
		View v = mLayoutInflater.inflate(R.layout.thumbnail_view, null);
		mThumbnailMain.addView(v, 0);
		
		DisplayMetrics metrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(metrics);
		
		int sizeW = (int)(100 * metrics.density);
		int sizeH = (int)(100 * metrics.density);
		int margin = (int)(20 * metrics.density);
		
		ImageView imv = (ImageView)v;
		v.setTag(row);
		
		imv.setImageBitmap(Bitmap.createScaledBitmap(BitmapFactory.decodeFile(row.getString("SCENE_PIC_LOCATION", "")), 120, 120, true));
		LayoutParams params = new LayoutParams(sizeW, sizeH);
		params.setMargins(margin, 0, 0, 0);
		imv.setLayoutParams(params);
		
		v.setOnDragListener(mOnDragListener);
		v.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View v) {
				
				// 버튼은 패스
				if(v instanceof Button)
					return false;
				
				mDrapView = v;
				
				ClipData data = ClipData.newPlainText("", "");
				MyDragShadowBuilder shadowBuilder = new MyDragShadowBuilder(mDrapView);
				mDrapView.startDrag(data, shadowBuilder, mDrapView, 0);
				
				return false;
			}
		});
	}
	
	private Bitmap getScaledDrawable(String picturePath, int w, int h) {
		Bitmap bitmap = BitmapFactory.decodeFile(picturePath);
		if(bitmap.getWidth() > w || bitmap.getHeight() > h){
			// 가로로 먼저 맞춘다. 
			float ratio = 1.0f;
			if(bitmap.getWidth() > w){
				ratio = ((float)w/(float)bitmap.getWidth());
			}
			// 세로도 맞춘다.
			else{
				ratio = ((float)h/(float)bitmap.getHeight());
			}
			
			int width = (int)((float)bitmap.getWidth()*ratio);
			int height = (int)((float)bitmap.getHeight()*ratio);
			return Bitmap.createScaledBitmap(bitmap, width, height, true);
		}else{
			return bitmap;	
		}
	}

	

	private void save(){
		// 일단 로컬에 저장한다.
		try{
			if(mSlipContainer.getChildCount() == 0)
				throw new Exception("내용을 입력해주시기 바랍니다.");

			String sceneInsDt = StringUtil.currentDate("yyyyMMddHHmmss");
			String firstText = "";
			Bitmap firstBitmap = null;

			DataTable sceneDetailList = new DataTable();
			
			for(int i=0; i<mSlipContainer.getSlipCount(); i++){
				SceneView sceneView = (SceneView)mSlipContainer.getChildAtIndex(i);

				DataRow item = (DataRow) sceneView.getTag();
				item.put("SCENE_SORT_ORDER", i + "");
				item.put("SCENE_INS_DT", sceneInsDt);
				String sceneText = sceneView.getSceneText();
				item.put("SCENE_TEXT", sceneText);
				sceneDetailList.add(item);
				if(i == 0){
					firstBitmap = BitmapFactory.decodeFile(item.getString("SCENE_PIC_LOCATION", ""));
					firstText = sceneText;
				}
			}

			String sceneDate = mButtonSceneDate.getTag().toString();
			String alarmDate = mButtonAlarmTime.getText().toString();
			if(alarmDate.startsWith("No")){
				alarmDate = "";
			}
			
			DataRow headerData = new DataRow();
			headerData.put("SCENE_INS_DT", sceneInsDt);
			headerData.put("SCENE_DATE", sceneDate);
			headerData.put("ALARM_DATE", alarmDate);
			
			String shortCutYn = mToggleShortCut.isChecked() ? "Y" : "N";
			
			String gpsUseYn = mToggleGps.isChecked() ? "Y" : "N";
			headerData.put("LOCATION_USE_YN", gpsUseYn);

			String sceneId = "";
			if(mData != null){
				sceneId = mData.getString("SCENE_ID", "");
				headerData.put("SCENE_ID", sceneId);
				mDao.updateScene(headerData, sceneDetailList);
				updateAlarm(sceneId, alarmDate, firstText);
			}else{
				sceneId = mDao.insertScene(headerData, sceneDetailList);
				updateAlarm(sceneId, alarmDate, firstText);
			}
			
			if(gpsUseYn.equals("Y")){
				mExifUtil.saveGpsData(MakeSlipActivity.this, sceneDetailList);
			}
			
			if(shortCutYn.equals("Y")){
				getShortcutUtil().shorcutScene(firstBitmap, sceneId, firstText);
			}
			
			setResult(Activity.RESULT_OK);
			finish();
			
		}catch(Exception e){
			errorHandler(e);
		}
	}
	
	private void updateAlarm(String sceneId, String alarmDate, String sceneTxt) throws Exception {
		
		String alarmBefore = mButtonAlarmTime.getText().toString();
		if(alarmBefore.startsWith("No"))
			return;
		
		if(alarmBefore.equals("5min")){
			
		}else if(alarmBefore.equals("10min")){
			
		}else if(alarmBefore.equals("15min")){
			
		}else if(alarmBefore.equals("30min")){
			
		}else if(alarmBefore.equals("1hour")){
			
		}else if(alarmBefore.equals("2hour")){
			
		}else if(alarmBefore.equals("6hour")){
			
		}
		
		// 수정하러 들어왔는데, 알람을 해제한 경우
//		if(!mToggleAlarm.isChecked() && mData != null){
//			int sceneIdAsInteger = Integer.parseInt(mData.getString("SCENE_ID", "0"));
//			releaseAlarm(this, sceneIdAsInteger);
//		}else if(mToggleAlarm.isChecked()){
//			int sceneIdAsInteger = Integer.parseInt(sceneId);
//			long alarmT = Long.parseLong(alarmDate);
//			setAlarm(this, alarmT, sceneIdAsInteger, "Daily Scene", sceneTxt);
//		}
		
	}

	@Override
	public boolean onLongClick(View v) {
		int id = v.getId();
		switch(id){
		case R.id.imv_picture:
			choosePic();
			break;
		}
		return false;
	}

	
	private void bindDrapListener(View v) {
		v.setOnDragListener(mOnDragListener);
		v.setOnClickListener(this);
		v.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View v) {
				
				// 버튼은 패스
				if(v instanceof Button)
					return false;
				
				mDrapView = v;
				ClipData data = ClipData.newPlainText("", "");
				MyDragShadowBuilder shadowBuilder = new MyDragShadowBuilder(mDrapView);
				mDrapView.startDrag(data, shadowBuilder, mDrapView, 0);
				
				long[] pattern = {0, 200, 400};
				Vibrator vi = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
				vi.vibrate(pattern, 2);
				
				return false;

			}
		});
	}

	private OnDragListener mOnDragListener = new OnDragListener() {

		@Override
		public boolean onDrag(View v, DragEvent event) {
			
			switch (event.getAction()) {
			case DragEvent.ACTION_DRAG_STARTED:
				// Do nothing
				break;
			case DragEvent.ACTION_DRAG_ENTERED:
				v.setAlpha(0.75F);
				if(v instanceof Button)
					((Button)v).performClick();
				break;
			case DragEvent.ACTION_DRAG_EXITED:
				v.setAlpha(1F);
				break;
			case DragEvent.ACTION_DROP:
				View view = (View) event.getLocalState();
				if(view instanceof Button)
					break;
				
				for (int i = 0; i < mThumbnailMain.getChildCount(); i++) {
					if (mThumbnailMain.getChildAt(i) == v) {
						mThumbnailMain.removeView(view);
						mThumbnailMain.addView(view, i);
						break;
					}
				}
				
				reOrderSortOrder();
				
				break;
			case DragEvent.ACTION_DRAG_ENDED:
				v.setAlpha(1.0F);
				break;

			default:
				break;
			}
			return true;

		}
	};
	
	private class MyDragShadowBuilder extends View.DragShadowBuilder {

		private final WeakReference<View> mView;

		public MyDragShadowBuilder(View view) {
			super(view);
			mView = new WeakReference<View>(view);
		}

		@Override
		public void onDrawShadow(Canvas canvas) {
			canvas.scale(1.5f, 1.5f);
			super.onDrawShadow(canvas);
		}

		@Override
		public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
			final View view = mView.get();
			if (view != null) {
				shadowSize.set((int) (view.getWidth() * 1.0F), (int) (view.getHeight() * 1.0F));
				shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
			} 
		}
	}

	protected void reOrderSortOrder() {
		
		mSlipContainer.saveCurrentInstance();
		
		mSlipContainer.removeAllSlips();
		for(int i=0; i<mThumbnailMain.getChildCount(); i++){
			final ImageView v = (ImageView) mThumbnailMain.getChildAt(i);
			if(!(v.getTag() instanceof DataRow))
				continue;
			DataRow row = (DataRow)v.getTag();
			addSlipView(row, false);
		}
	}

	@Override
	public void PageScrollCompleted(final int index, int totalCount) {
		runOnUiThread(new Runnable(){
			@Override
			public void run() {
				RelativeLayout layout = (RelativeLayout)mSlipContainer.getMainContainer().getChildAt(index);
				((View)(layout.findViewById(R.id.edt_memo))).requestFocus();		
			}
		});
	}
	
}
